package sg.edu.nus.iss.vmcs.maintenance;

/*
 * Copyright 2011 ISS.
 * The contents contained in this document may not be reproduced in any
 * form or by any means, without the written permission of ISS, other
 * than for the purpose for which it has been supplied.
 *
 */

import java.awt.*;

import sg.edu.nus.iss.vmcs.store.*;
import sg.edu.nus.iss.vmcs.system.*;
import sg.edu.nus.iss.vmcs.machinery.*;
import sg.edu.nus.iss.vmcs.util.*;
import sg.edu.nus.iss.vmcs.customer.TransactionController;

/**
 * This class represents the controller object that handles the system maintenance
 * related operations and communicates between the user interface objects and entity
 * objects. It manages the login / logout process through loginMaintainer and
 * logoutMaintainer.
 *
 * @version 1.0  08/12/2011
 * @author Team 7S - SE19
 */

public class MaintenanceController {

	private MainController mCtrl;
	private MaintenancePanel mpanel;
	private AccessManager am;

/**
 * This constructor creates an instance of the Maintenance Controller.
 * @param mctrl Main Controller
 * @see MainController
 */	
	public MaintenanceController(MainController mctrl) {
		mCtrl = mctrl;
		am = new AccessManager(this);
	}

/**
 * This operation gets the reference of the MainController object
 * @return MainConroller
 */	
	public MainController getMainController() {
		return mCtrl;
	}

/**
 * This operation setup and initialize the maintenance panel and display it.
 * @see MaintenancePanel
 */
	public void displayMaintenancePanel() {
		SimulatorControlPanel scp = mCtrl.getSimulatorControlPanel();
		if (mpanel == null)
			mpanel = new MaintenancePanel((Frame) scp, this);
		mpanel.display();
		mpanel.setActive(MaintenancePanel.DIALOG, true);
		// setActive of password, invalid and valid display.
	}

/**
 * This operation retrieves/gets the AccessManager object
 * @return am AccessManager
 * @see AccessManager
 */	
	public AccessManager getAccessManager() {
		return am;
	}

/**
 * This operation set the state of the password upon login. Also it checks
 * for successful login and accordingly set the MaintenancePanel to active
 * for working purpose and disable the password. It also receives the reference
 * for the Machinery Controller object and set the state of the door object as false. 
 * @param st boolean state of the password (TRUE / FALSE)
 * @see MaintenancePanel
 * @see MachineryController
 */	
	public void loginMaintainer(boolean st) {
		mpanel.displayPasswordState(st);
		mpanel.clearPassword();
		if (st == true) {
			// login successful
			TransactionController tCtrl = mCtrl.getTransactionController();
			tCtrl.terminateTransaction();
			tCtrl.getCustomerPanel().getTerminateBtn().setEnabled(false);
			mpanel.setActive(MaintenancePanel.WORKING, true);
			mpanel.setActive(MaintenancePanel.PSWD, false);
			MachineryController machctrl = mCtrl.getMachineryController();
			machctrl.setDoorState(false);
		}
	}

	// invoked in CoinDisplayListener
/**
 * This operation will be used to get the total number of coins of a selected
 * denomination.
 * @param idx index associated to StoreItem (Cash Store)
 * @see StoreController
 * @see CashStoreItem
 * @see CoinDisplay
 * @see MaintenancePanel
 */	
	public void displayCoin(int idx) {
		StoreController sctrl = mCtrl.getStoreController();
		CashStoreItem item;
		try {
			item = (CashStoreItem) sctrl.getStoreItem(Store.CASH, idx);
			mpanel.getCoinDisplay().displayQty(idx, item.getQuantity());
		} catch (VMCSException e) {
			System.out.println("MaintenanceController.displayCoin:" + e);
		}

	}

	// invoked in DrinkDisplayListener;
	
/**
 * This operation will get the drink stock value and prices (for a specific brand) for display.
 * @param idx index associated to StoreItem (Drinks Store)
 * @see StoreController
 * @see DrinksStoreItem
 * @see DrinksBrand
 * @see DrinkDisplay
 * @see MaintenancePanel
 */
	public void displayDrinks(int idx) {
		StoreController sctrl = mCtrl.getStoreController();
		DrinksStoreItem item;
		try {
			item = (DrinksStoreItem) sctrl.getStoreItem(Store.DRINK, idx);
			DrinksBrand db = (DrinksBrand) item.getContent();
			mpanel.getDrinksDisplay().displayQty(idx, item.getQuantity());
			mpanel.displayPrice(db.getPrice());
		} catch (VMCSException e) {
			System.out.println("MaintenanceController.displayDrink:" + e);
		}

	}

	// invoked by PriceDisplayListener
/**
 * This operation will be used to set the price of a drink brand as determined
 * by the Maintainer
 * @param pr integer Price of the drink brand
 */	
	public void setPrice(int pr) {
		StoreController sctrl = mCtrl.getStoreController();
		int curIdx = mpanel.getCurIdx();
		sctrl.setPrice(curIdx, pr);
		mpanel.getDrinksDisplay().getPriceDisplay().setValue(pr + "C");
	}

	// TotalCashButtonListener
/**
 * This operation sends the total cash held in the cash store to the Maintenance
 * Panel.
 * @see StoreController
 */	
	public void getTotalCash() {
		StoreController sctrl = mCtrl.getStoreController();
		int tc = sctrl.getTotalCash();
		mpanel.displayTotalCash(tc);

	}

	// TransferCashButtonListener
	// get all the cash from store and set store cash 0;
/**
 * This operation is to facilitate the transfer of all cash in Cash Store and
 * set the cash store 0
 * @see StoreController
 * @see MachineryController
 */	
	public void transferAll() {
		StoreController sctrl = mCtrl.getStoreController();
		MachineryController machctrl = mCtrl.getMachineryController();

		int cc; // coin quantity;

		try {

			cc = sctrl.transferAll();
			mpanel.displayCoins(cc);
			machctrl.displayCoinStock();
			// the cash quantity current is displayed in the Maintenance panel needs to be update to be 0;
			// not required.
			mpanel.updateCurrentQtyDisplay(Store.CASH, 0);
		} catch (VMCSException e) {
			System.out.println("MaintenanceController.transferAll:" + e);
		}
	}

	// StoreViewerListener
/**
 * This operation updates the quantity to be displayed at the panel based
 * on the type (CASH, DRINK) 
 * @param type Type is either CASH or DRINK
 * @param idx Index within the Store for Cash or Drinks
 * @param qty Quantity to be updated
 * @see MaintenancePanel
 */
	public void changeStoreQty(char type, int idx, int qty) {
		//StoreController sctrl = mCtrl.getStoreController();

		try {
			mpanel.updateQtyDisplay(type, idx, qty);
			mpanel.initCollectCash();
			mpanel.initTotalCash();
		} catch (VMCSException e) {
			System.out.println("MaintenanceController.changeStoreQty:" + e);
		}
	}

	// exit button listener;
/**
 * This operation will check for logout in terms of door locked TRUE / FASLE.
 * If successfully locked it will reset the maintenance panel and update
 * the customer panel and permit customer transaction to re-start.
 * @see MachineryController
 */
	public void logoutMaintainer() {

		MachineryController machctrl = mCtrl.getMachineryController();

		boolean ds = machctrl.isDoorClosed();

		if (ds == false) {
			MessageDialog msg =
				new MessageDialog(
					mpanel,
					"Please Lock the Door before You Leave");
			msg.setLocation(500, 500);
			return;
		}

		TransactionController tCtrl = mCtrl.getTransactionController();
		if (tCtrl.getCustomerPanel() != null) {
			tCtrl.getCustomerPanel().getTerminateBtn().setEnabled(true);
			tCtrl.getDispenseCtrl().allowSelection(true);
		}
		mpanel.setActive(MaintenancePanel.DIALOG, true);
		this.closeDown();
	}

/**
 *  This operation will close down the maintenance functions of the maintenance
 *  simulation panel
 */
	public void closeDown() {
		if (mpanel != null) {
			mpanel.closeDown();
 			SimulatorControlPanel scp = mCtrl.getSimulatorControlPanel();
 			scp.setActive(SimulatorControlPanel.ACT_MAINTAINER, true);
		}
	}

}